package com.shupian.handler.exception;

import com.shupian.domain.ResponseResult;
import com.shupian.enums.AppHttpCodeEnum;
import com.shupian.exception.SystemException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import javax.xml.bind.ValidationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 处理自定义异常
     * @param e
     * @return
     */
    @ExceptionHandler(SystemException.class)
    public ResponseResult systemException(SystemException e){
        //打印异常信息
        log.error("出现了异常！{}",e);
        //从异常对象中获取异常现象 封装返回
        return ResponseResult.errorResult(e.getCode(),e.getMsg());


    }

    /**
     * 方法参数不合法
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        Map<String, String> collect = e.getBindingResult().getFieldErrors().stream()
                .collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
        return ResponseResult.errorResult(AppHttpCodeEnum.VALUE_ERROR,collect);
    }

    /**
     * ValidationException
     */
    @ExceptionHandler(ValidationException.class)
    public ResponseResult handleValidationException(ValidationException e) {
        log.error(e.getMessage(), e);
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAMETER_VALIDATION_ERROR, e.getCause().getMessage());
    }

    /**
     * ConstraintViolationException
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseResult handleConstraintViolationException(ConstraintViolationException e) {
        log.error(e.getMessage(), e);
        Map<String, String> map = new HashMap<>();
        for (ConstraintViolation<?> constraintViolation : e.getConstraintViolations()) {
            String message = constraintViolation.getMessage();
            String name = constraintViolation.getPropertyPath().toString();
            //log.info("keys,{}",name);
            String[] split = name.split("\\.");

            //for (String s : split) {
            //    log.info("key,{}", s);
            //}
            name = split[split.length-1];

            map.put(name,message);
        }
        //Map<Path, String> collect1 = e.getConstraintViolations().stream()
        //        .collect(Collectors.toMap(ConstraintViolation::getPropertyPath, ConstraintViolation::getMessage));
        ////List<String> collect = e.getConstraintViolations().stream().map(item -> item.getMessage()).collect(Collectors.toList());
        return ResponseResult.errorResult(AppHttpCodeEnum.VALUE_ERROR, map);
    }
    //
    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseResult handlerNoFoundException(Exception e) {
        log.error(e.getMessage(), e);
        return ResponseResult.errorResult(404, "路径不存在，请检查路径是否正确");
    }
    //
    //@ExceptionHandler(DuplicateKeyException.class)
    //public MethodArgumentNotValidException handleDuplicateKeyException(DuplicateKeyException e) {
    //    log.error(e.getMessage(), e);
    //    return new ResponseResult(DUPLICATE_KEY_CODE, "数据重复，请检查后提交");
    //}




    @ExceptionHandler(Exception.class)
    public ResponseResult systemException(Exception e) {
        //打印异常信息
        log.error("出现了异常！{}", e);
        //从异常对象中获取异常现象 封装返回
        return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR.getCode(),e.getMessage());


    }


}
